# cmake_minimum_required(VERSION <specify CMake version here>)
cmake_minimum_required(VERSION 3.11)
project(LinuxEnvironmentProgramming)

set(CMAKE_CXX_STANDARD 14)

add_executable(LinuxEnvironmentProgramming A/main.cpp)


add_executable(StandardIOTest01 Test/IO/StandardIO/StandardIOTest01.cpp)
add_executable(StandardIOTest02 Test/IO/StandardIO/StandardIOTest02.cpp)
add_executable(StandardIOTest03 Test/IO/StandardIO/StandardIOTest03.cpp)
add_executable(StandardIOTest04 Test/IO/StandardIO/StandardIOTest04.cpp)
add_executable(StandardIOTest05 Test/IO/StandardIO/StandardIOTest05.cpp)
add_executable(StandardIOTest06 Test/IO/StandardIO/StandardIOTest06.cpp)
add_executable(StandardIOTest07 Test/IO/StandardIO/StandardIOTest07.cpp)
add_executable(StandardIOTest08 Test/IO/StandardIO/StandardIOTest08.cpp)


add_executable(FileIOTest01 Test/IO/FileIO/FileIOTest01.cpp)
add_executable(FileIOTest02 Test/IO/FileIO/FileIOTest02.cpp)
add_executable(FileIOTest03 Test/IO/FileIO/FileIOTest03.cpp)


add_executable(FileSystemTest01 Test/FileSystem/FileSystemTest01.cpp)
add_executable(FileSystemTest02 Test/FileSystem/FileSystemTest02.cpp)
add_executable(FileSystemTest03 Test/FileSystem/FileSystemTest03.cpp)
add_executable(FileSystemTest04 Test/FileSystem/FileSystemTest04.cpp)
add_executable(FileSystemTest05 Test/FileSystem/FileSystemTest05.cpp)
add_executable(FileSystemTest06 Test/FileSystem/FileSystemTest06-username.cpp)
add_executable(FileSystemTest07 Test/FileSystem/FileSystemTest07-chkpass.cpp)
add_executable(FileSystemTest08 Test/FileSystem/FileSystemTest08-timelog.cpp)
add_executable(FileSystemTest09 Test/FileSystem/FileSystemTest09.cpp)
add_executable(FileSystemTest10 Test/FileSystem/FileSystemTest10.cpp)
add_executable(FileSystemTest11 Test/FileSystem/FileSystemTest11.cpp)
add_executable(FileSystemTest12 Test/FileSystem/FileSystemTest12.cpp)
add_executable(FileSystemTest13 Test/FileSystem/FileSystemTest13-getenv.cpp)
add_executable(FileSystemTest14 Test/FileSystem/FileSystemTest14.cpp)


add_executable(IPCTest01 Test/IPC/IPCTest01.cpp)
add_executable(IPCTest02 Test/IPC/IPCTest02-prime-number.cpp)
add_executable(IPCTest03 Test/IPC/IPCTest03-prime-number.cpp)
add_executable(IPCTest04 Test/IPC/IPCTest04-prime-number.cpp)
add_executable(IPCTest05 Test/IPC/IPCTest05-prime-number.cpp)
add_executable(TestFor Test/IPC/TestFor.cpp)
add_executable(IPCTest06 Test/IPC/IPCTest06.cpp)
add_executable(IPCTest07 Test/IPC/IPCTest07.cpp)
add_executable(IPCTest08 Test/IPC/IPCTest08-my-shell.cpp)
add_executable(IPCTest09 Test/IPC/IPCTest09-my-su.cpp)
add_executable(IPCTest10 Test/IPC/Daemon/IPCTest10-my-daemon.cpp)
add_executable(IPCTest11 Test/IPC/Daemon/IPCTest11-my-daemon.cpp)


add_executable(SignalTest01 Test/Concurrency/Parallel/Signal/SignalTest01.cpp)
add_executable(SignalTest02 Test/Concurrency/Parallel/Signal/SignalTest02-FileIOTest01.cpp)
add_executable(AlarmTest01 Test/Concurrency/Parallel/Signal/AlarmTest01.cpp)
add_executable(AlarmTest02 Test/Concurrency/Parallel/Signal/AlarmTest02.cpp)
add_executable(AlarmTest03 Test/Concurrency/Parallel/Signal/AlarmTest03.cpp)
add_executable(SignalTest03 Test/Concurrency/Parallel/Signal/SignalTest03-MyCat.cpp)
add_executable(SignalTest04 Test/Concurrency/Parallel/Signal/SignalTest04-SlowCat.cpp)
add_executable(SignalTest05 Test/Concurrency/Parallel/Signal/SignalTest05-SlowCat2.cpp)
####################################################

# 将SignalTest05-SlowCat2.cpp重构成一个库。
# 这次失败了, 原因是想一次就完成最终想优化的结果。事实是这种想法和做法是不正确不科学的, 敏捷开发要一步一步来, 一步一步重构, 一步一步提升！！！！
# 谨记！！！！
add_executable(MyTBF Test/Concurrency/Parallel/Signal/MyTBF/main.cpp
        Test/Concurrency/Parallel/Signal/MyTBF/MyTBF.cpp
        Test/Concurrency/Parallel/Signal/MyTBF/MyTBF.hpp)


# MyTBF目录的惨痛教训, 现在我重新进行库的编写。在目录 MyTBF2下。
add_executable(MyTBF2 Test/Concurrency/Parallel/Signal/MyTBF2/main.cpp
        Test/Concurrency/Parallel/Signal/MyTBF2/MyTBF.cpp
        Test/Concurrency/Parallel/Signal/MyTBF2/MyTBF.hpp)
####################################################
# 任意时刻的定时器 AnyTimer
add_executable(AnyTimer Test/Concurrency/Parallel/Signal/AnyTimer/main.cpp
        Test/Concurrency/Parallel/Signal/AnyTimer/AnyTimer.cpp
        Test/Concurrency/Parallel/Signal/AnyTimer/AnyTimer.hpp)

####################################################

add_executable(SignalTest06 Test/Concurrency/Parallel/Signal/SignalTest06-SlowCat-setitimer.cpp)
add_executable(SignalTest07 Test/Concurrency/Parallel/Signal/SignalTest07.cpp)
add_executable(SignalTest08 Test/Concurrency/Parallel/Signal/SignalTest08.cpp)
add_executable(SignalTest09 Test/Concurrency/Parallel/Signal/SignalTest09-IPCTest11-my-daemon.cpp)

####################################################
# 对流控进行改进(使用 sigaction()函数)
add_executable(MyTBF2-sigaction Test/Concurrency/Parallel/Signal/MyTBF2-sigaction/main.cpp
        Test/Concurrency/Parallel/Signal/MyTBF2-sigaction/MyTBF.cpp
        Test/Concurrency/Parallel/Signal/MyTBF2-sigaction/MyTBF.hpp)

####################################################

add_executable(SignalTest10 Test/Concurrency/Parallel/Signal/SignalTest10.cpp)


# 不知道在CMake中如何在编译和链接时加入  -pthread。
#add_compile_options(pthread)
#add_link_options(pthread)
#COMPILE_FLAGS(-pthread)
#LINK_FLAGS(-pthread)

#set_target_properties(${TARGET} PROPERTIES
#        COMPILE_FLAGS "-pthread"
#        LINK_FLAGS "-pthread")

###############################
# 使用g++编译链接 pthread库的时候需要这样:
# g++ ThreadTest01-create.cpp -lpthread
# 或者:
# g++ ThreadTest01-create.cpp -pthread
###############################


#target_link_libraries(LinuxEnvironmentProgramming ${CMAKE_THREAD_LIBS_INIT})

#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")


#set(THREADS_PREFER_PTHREAD_FLAG ON)
#find_package(Threads REQUIRED)
#target_link_libraries(LinuxEnvironmentProgramming Threads::Threads)

add_executable(ThreadTest01 Test/Concurrency/Parallel/Thread/posix/ThreadTest01-create.cpp)
add_executable(ThreadTest02 Test/Concurrency/Parallel/Thread/posix/ThreadTest02-exit.cpp)
add_executable(ThreadTest03 Test/Concurrency/Parallel/Thread/posix/ThreadTest03-join.cpp)
add_executable(ThreadTest04 Test/Concurrency/Parallel/Thread/posix/ThreadTest04-cleanup.cpp)
add_executable(ThreadTest05 Test/Concurrency/Parallel/Thread/posix/ThreadTest05-log.cpp)
add_executable(ThreadTest06 Test/Concurrency/Parallel/Thread/posix/ThreadTest06-IPCTest02-prime-number.cpp)
add_executable(ThreadTest07 Test/Concurrency/Parallel/Thread/posix/ThreadTest07.cpp)


#TARGET_LINK_LIBRARIES(编译目标名称target 标准库名称)
# 参考文章
# https://blog.csdn.net/ly890700/article/details/72806033?utm_source=itdadao&utm_medium=referral
add_executable(ThreadTest08 Test/Concurrency/Parallel/Thread/posix/ThreadTest08.cpp)
target_link_libraries(ThreadTest08 pthread)

# 为之后所有的目标都在编译链接时使用pthread库。
LINK_LIBRARIES(pthread)
add_executable(ThreadTest09 Test/Concurrency/Parallel/Thread/posix/ThreadTest09.cpp)
add_executable(ThreadTest10 Test/Concurrency/Parallel/Thread/posix/ThreadTest10.cpp)

###################################################################
# 这里我查了一下我的 remote host是几核的?
# 1核

# 参考: https://www.php.cn/linux-439975.html

# 1、查看物理CPU的个数
# #cat /proc/cpuinfo |grep "physical id"|sort |uniq|wc -l
# 2、查看逻辑CPU的个数（在线学习视频教程分享：linux视频教程）
# #cat /proc/cpuinfo |grep "processor"|wc -l
# 3、查看CPU是几核
# #cat /proc/cpuinfo |grep "cores"|uniq
# 4、查看CPU的主频
# #cat /proc/cpuinfo |grep MHz|uniq

###################################################################
# 对于程序11来说, 因为我是单核。所以模拟不出来 abababab acabababacbc等
# 结果只能是 aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbb cccccccccccccc aaaaaaaaaaaaaaaaaa 这样的时间片轮转。
add_executable(ThreadTest11 Test/Concurrency/Parallel/Thread/posix/ThreadTest11.cpp)

add_executable(ThreadTest12 Test/Concurrency/Parallel/Thread/posix/ThreadTest12.cpp)
add_executable(ThreadTest13 Test/Concurrency/Parallel/Thread/posix/ThreadTest13.cpp)

# 将之前的信号令牌桶重构为线程令牌桶
add_executable(MyTBF2-Thread Test/Concurrency/Parallel/Thread/posix/MyTBF2-Thread/main.cpp
        Test/Concurrency/Parallel/Thread/posix/MyTBF2-Thread/MyTBF.cpp
        Test/Concurrency/Parallel/Thread/posix/MyTBF2-Thread/MyTBF.hpp)

add_executable(MyTBF2-Thread-2 Test/Concurrency/Parallel/Thread/posix/MyTBF2-Thread-2/main.cpp
        Test/Concurrency/Parallel/Thread/posix/MyTBF2-Thread-2/MyTBF.cpp
        Test/Concurrency/Parallel/Thread/posix/MyTBF2-Thread-2/MyTBF.hpp)

add_executable(ThreadTest14 Test/Concurrency/Parallel/Thread/posix/ThreadTest14.cpp)
add_executable(ThreadTest15 Test/Concurrency/Parallel/Thread/posix/ThreadTest15.cpp)
add_executable(ThreadTest16 Test/Concurrency/Parallel/Thread/posix/ThreadTest16.cpp)

######################################################################
# 信号量的学习 semaphore
add_executable(MySemaphore Test/Concurrency/Parallel/Thread/posix/MySemaphore/main.cpp
        Test/Concurrency/Parallel/Thread/posix/MySemaphore/MySemaphore.cpp
        Test/Concurrency/Parallel/Thread/posix/MySemaphore/MySemaphore.hpp)
######################################################################

# openmp线程标准简单介绍
add_executable(ThreadTest17 Test/Concurrency/Parallel/Thread/posix/ThreadTest17.cpp)
#target_link_libraries(ThreadTest17 fopenmp)


# AdvancedIOTest01和AdvancedIOTest02运行的时候都是盲等的, 可以看到CPU的使用率一下就占满一个核。
# 如果是双核, 那就占满一个核; 如果是单核, 也是直接占满一个核。
add_executable(AdvancedIOTest01 Test/IO/AdvancedIO/Nonblocking/AdvancedIOTest01-relay.cpp)
add_executable(AdvancedIOTest02 Test/IO/AdvancedIO/Nonblocking/Relayer/AdvancedIOTest02-relayer.cpp
        Test/IO/AdvancedIO/Nonblocking/Relayer/Relayer.cpp
        Test/IO/AdvancedIO/Nonblocking/Relayer/Relayer.hpp)
add_executable(AdvancedIOTest03 Test/IO/AdvancedIO/Nonblocking/Select/AdvancedIOTest03.cpp)
add_executable(AdvancedIOTest04 Test/IO/AdvancedIO/Nonblocking/Poll/AdvancedIOTest04.cpp)
add_executable(AdvancedIOTest05 Test/IO/AdvancedIO/Nonblocking/Epoll/AdvancedIOTest05.cpp)

# 随意指出一个文件, 计算这个文件中有多少个'a'字符。
add_executable(AdvancedIOTest06 Test/IO/AdvancedIO/Nonblocking/mmap/AdvancedIOTest06.cpp)
# 使用mmap()来实现父子进程间的通信。以及通过mmap()来进行malloc()。
add_executable(AdvancedIOTest07 Test/IO/AdvancedIO/Nonblocking/mmap/AdvancedIOTest07.cpp)
# 文件锁
add_executable(AdvancedIOTest08 Test/IO/AdvancedIO/Nonblocking/lockf/AdvancedTest08-ThreadTest09.cpp)


######################################################################
add_executable(TestMyPipe Test/Concurrency/Parallel/Thread/posix/MyPipe/TestMyPipe.cpp
        Test/Concurrency/Parallel/Thread/posix/MyPipe/MyPipe.cpp
        Test/Concurrency/Parallel/Thread/posix/MyPipe/MyPipe.hpp)
######################################################################


######################################################################
# IPC: inter-process communication

# Pipe
add_executable(PipeTest01 Test/IPC/Pipe/PipeTest01.cpp)

######################################################################
# XSI

# msg

# 这是同一个主机下的没有亲缘关系的不同进程之间的通信, 基于消息队列。
add_executable(msgTest01-sender Test/IPC/XSI/msg/basic/MsgTest01-sender.cpp
        Test/IPC/XSI/msg/basic/Proto.cpp
        Test/IPC/XSI/msg/basic/Proto.hpp)

add_executable(msgTest01-receiver Test/IPC/XSI/msg/basic/MsgTest01-receiver.cpp
        Test/IPC/XSI/msg/basic/Proto.cpp
        Test/IPC/XSI/msg/basic/Proto.hpp)

# my ftp协议的实现。
add_executable(MyFTP-sender Test/IPC/XSI/msg/my_ftp/TestMyFTP-sender
        Test/IPC/XSI/msg/my_ftp/proto.cpp
        Test/IPC/XSI/msg/my_ftp/proto.hpp
        Test/IPC/XSI/msg/my_ftp/proto2.hpp)
add_executable(MyFTP-receiver Test/IPC/XSI/msg/my_ftp/TestMyFTP-receiver.cpp
        Test/IPC/XSI/msg/my_ftp/proto.cpp
        Test/IPC/XSI/msg/my_ftp/proto.hpp
        Test/IPC/XSI/msg/my_ftp/proto2.hpp)

######################################################################
# XSI

# sem
add_executable(SemTest01 Test/IPC/XSI/sem/SemTest01-AdvancedTest08-ThreadTest09.cpp)

######################################################################
# XSI

# shm
add_executable(ShmTest01 Test/IPC/XSI/shm/shm-Test01.cpp)

######################################################################


######################################################################
# socket

add_executable(SocketTest01-sender Test/IPC/Socket/datagram/basic/SocketTest01-sender.cpp
        Test/IPC/Socket/datagram/basic/Proto.cpp Test/IPC/Socket/datagram/basic/Proto.hpp)
add_executable(SocketTest01-receiver Test/IPC/Socket/datagram/basic/SocketTest01-receiver.cpp
        Test/IPC/Socket/datagram/basic/Proto.cpp Test/IPC/Socket/datagram/basic/Proto.hpp)

# 动态udp报
add_executable(SocketTest02-sender Test/IPC/Socket/datagram/var/SocketTest01-sender.cpp
        Test/IPC/Socket/datagram/var/Proto.cpp Test/IPC/Socket/datagram/var/Proto.hpp)
add_executable(SocketTest02-receiver Test/IPC/Socket/datagram/var/SocketTest01-receiver.cpp
        Test/IPC/Socket/datagram/var/Proto.cpp Test/IPC/Socket/datagram/var/Proto.hpp)


# 广播

# 我在CentOS上下载了 wireshark 进行抓包, 在软件库里面下载的, 下载后做如下操作, 必须！！
# [root@localhost ~]# sudo chgrp liuyou /usr/bin/dumpcap
# [root@localhost ~]# chmod  750 /usr/sbin/dumpcap
# [root@localhost ~]# sudo setcap cap_net_raw,cap_net_admin+eip /usr/bin/dumpcap
# 之后 wireshark 就会自动检测, 并可以普通用户使用。
add_executable(SocketTest03-sender Test/IPC/Socket/datagram/broadcast/SocketTest01-sender.cpp
        Test/IPC/Socket/datagram/broadcast/Proto.cpp Test/IPC/Socket/datagram/broadcast/Proto.hpp)
add_executable(SocketTest03-receiver Test/IPC/Socket/datagram/broadcast/SocketTest01-receiver.cpp
        Test/IPC/Socket/datagram/broadcast/Proto.cpp Test/IPC/Socket/datagram/broadcast/Proto.hpp)


# 多播/组播
# 多播/组播输入D类地址: 224.开头
add_executable(SocketTest04-sender Test/IPC/Socket/datagram/multicast/SocketTest01-sender.cpp
        Test/IPC/Socket/datagram/multicast/Proto.cpp Test/IPC/Socket/datagram/multicast/Proto.hpp)
add_executable(SocketTest04-receiver Test/IPC/Socket/datagram/multicast/SocketTest01-receiver.cpp
        Test/IPC/Socket/datagram/multicast/Proto.cpp Test/IPC/Socket/datagram/multicast/Proto.hpp)


# 流式套接字
add_executable(SocketTest05-server
        Test/IPC/Socket/stream/basic/Protocol.cpp Test/IPC/Socket/stream/basic/Protocol.hpp
        Test/IPC/Socket/stream/basic/SocketTest05-Server.cpp)
add_executable(SocketTest05-client
        Test/IPC/Socket/stream/basic/Protocol.cpp Test/IPC/Socket/stream/basic/Protocol.hpp
        Test/IPC/Socket/stream/basic/SocketTest05-Client.cpp)


# 并发版本流式套接字
add_executable(SocketTest06-server
        Test/IPC/Socket/stream/parallel/Protocol.cpp Test/IPC/Socket/stream/parallel/Protocol.hpp
        Test/IPC/Socket/stream/parallel/SocketTest05-Server.cpp)
add_executable(SocketTest06-client
        Test/IPC/Socket/stream/parallel/Protocol.cpp Test/IPC/Socket/stream/parallel/Protocol.hpp
        Test/IPC/Socket/stream/parallel/SocketTest05-Client.cpp)


# 静态进程池套接字实现
add_executable(SocketTest07-server
        Test/IPC/Socket/stream/pool_static/Protocol.cpp Test/IPC/Socket/stream/pool_static/Protocol.hpp
        Test/IPC/Socket/stream/pool_static/SocketTest05-Server.cpp)
add_executable(SocketTest07-client
        Test/IPC/Socket/stream/pool_static/Protocol.cpp Test/IPC/Socket/stream/pool_static/Protocol.hpp
        Test/IPC/Socket/stream/pool_static/SocketTest05-Client.cpp)


# 动态进程池套接字实现
add_executable(SocketTest08-server
        Test/IPC/Socket/stream/pool_dynamic/Protocol.cpp Test/IPC/Socket/stream/pool_dynamic/Protocol.hpp
        Test/IPC/Socket/stream/pool_dynamic/SocketTest05-Server.cpp)
add_executable(SocketTest08-client
        Test/IPC/Socket/stream/pool_dynamic/Protocol.cpp Test/IPC/Socket/stream/pool_dynamic/Protocol.hpp
        Test/IPC/Socket/stream/pool_dynamic/SocketTest05-Client.cpp)


########################################################################################################################


add_subdirectory(NetRadio/src/client)
add_subdirectory(NetRadio/src/server)

add_executable(NetRadio-Problem NetRadio/problem/Main.cpp NetRadio/problem/Main.hpp NetRadio/problem/People.cpp NetRadio/problem/People.hpp)